package com.wyx.controller.system;

import cn.hutool.core.date.DateUtil;
import com.wyx.aspectj.annotation.Log;
import com.wyx.aspectj.enums.BusinessType;
import com.wyx.constans.Constans;
import com.wyx.constans.HttpStatus;
import com.wyx.domain.LoginInfo;
import com.wyx.domain.Menu;
import com.wyx.domain.SimpleUser;
import com.wyx.dto.LoginBodyDto;
import com.wyx.service.LoginInfoService;
import com.wyx.service.MenuService;
import com.wyx.utils.AddressUtils;
import com.wyx.utils.IpUtils;
import com.wyx.utils.ShiroSecurityUtils;
import com.wyx.vo.ActiverUser;
import com.wyx.vo.AjaxResult;
import com.wyx.vo.MenuTreeVo;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @author xiaoxiong
 * @version 1.0
 * @date 2021/2/24 23:49
 */
@RestController
@Log4j2
public class LoginController {
    @Autowired
    private MenuService menuService;

    @Autowired
    private LoginInfoService loginInfoService;

    /**
     * 用户登陆
     *
     * @param loginBodyDto
     * @param request
     * @return
     */
    @PostMapping("login/doLogin")
    public AjaxResult login(@RequestBody @Validated LoginBodyDto loginBodyDto, HttpServletRequest request) {
        AjaxResult ajaxResult = AjaxResult.success("登录成功");
        String username = loginBodyDto.getUsername();
        String password = loginBodyDto.getPassword();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();
        //构造 LoginInfo信息
        LoginInfo loginInfo = getLoginInfo(request);
        loginInfo.setLoginAccount(loginBodyDto.getUsername());
        try {
            subject.login(token);
            // 得到会话，token
            Serializable webToken = subject.getSession().getId();
            ajaxResult.put(Constans.TOKEN, webToken);
            // 登陆成功 构造LoginInfo信息
            loginInfo.setLoginStatus(Constans.LOGIN_SUCCESS);
            loginInfo.setUserName(ShiroSecurityUtils.getCurrentUserName());
            loginInfo.setMsg("登陆成功");
        } catch (Exception e) {
            log.error("用户或者密码不正确", e);
            ajaxResult = AjaxResult.error(HttpStatus.ERROR, "用户或者密码不正确");
            // 登陆成功 构造LoginInfo信息
            loginInfo.setLoginStatus(Constans.LOGIN_SUCCESS);
            loginInfo.setMsg("登陆失败");
        }
        // 登陆日志存入数据库
        this.loginInfoService.insertLoginInfo(loginInfo);
        return ajaxResult;
    }

    /**
     * 获取用户登陆信息
     *
     * @return
     */
    @PostMapping("login/getInfo")
    public AjaxResult getInfo() {
        AjaxResult ajax = AjaxResult.success();
        Subject subject = SecurityUtils.getSubject();
        ActiverUser activerUser = (ActiverUser) subject.getPrincipal();
        ajax.put("username", activerUser.getUser().getUserName());
        ajax.put("picture", activerUser.getUser().getPicture());
        ajax.put("roles", activerUser.getRoles());
        ajax.put("permissions", activerUser.getPermissions());
        return ajax;
    }

    /**
     * 用户退出
     *
     * @return
     */
    @PostMapping("login/loginout")
    public AjaxResult logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return AjaxResult.success("用户退出成功");
    }


    /**
     * 获取用户的菜单信息
     *
     * @return
     */
    @GetMapping("login/getMenus")
    public AjaxResult getMenus() {
        Subject subject = SecurityUtils.getSubject();
        ActiverUser activerUser = (ActiverUser) subject.getPrincipal();
        boolean isAdmin = activerUser.getUser().getUserType().equals(Constans.USER_NORMAL);
        SimpleUser simpleUser = null;
        if (!isAdmin) {
            simpleUser = new SimpleUser(activerUser.getUser().getUserId(), activerUser.getUser().getUserName());
        }
        List<Menu> menus = menuService.selectMuneTree(isAdmin, simpleUser);
        ArrayList<MenuTreeVo> menuArrayList = new ArrayList<>();
        for (Menu menu : menus) {
            menuArrayList.add(new MenuTreeVo(menu.getMenuId().toString(), menu.getPath()));
        }
        return AjaxResult.success(menuArrayList);
    }


    public LoginInfo getLoginInfo(HttpServletRequest request) {
        LoginInfo loginInfo = new LoginInfo();
        // UserAgent 第三方jar包 主要用来获取浏览器请求的信息
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        loginInfo.setOs(userAgent.getOperatingSystem().getName());
        loginInfo.setBrowser(userAgent.getBrowser().getName());
        String ip = IpUtils.getIpAddr(request);
        loginInfo.setIpAddr(ip);
        loginInfo.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
        loginInfo.setLoginTime(DateUtil.date());
        loginInfo.setLoginType(Constans.LOGIN_TYPE_SYSTEM);
        return loginInfo;
    }
}
